package auto.app.service.impl;

import auto.app.config.RestUtil;
import auto.app.controller.from.*;
import auto.app.controller.from.BeforeAssertion.BeforeAssertionChickFrom;
import auto.app.controller.info.BeforeAssertion.BeforeAssertionChickInfo;
import auto.app.controller.info.CasePageInfo;
import auto.app.controller.info.CollectionPageInfo;
import auto.app.dao.CaseDao;
import auto.app.dao.ParamsDao;
import auto.app.exetion.MainExection;
import auto.app.model.*;
import auto.app.dao.TestCollectionDao;
import auto.app.model.Result;
import auto.app.service.*;
import auto.app.util.*;
import auto.app.vo.AutoExtractionRedis;
import auto.app.vo.MysqlReturn;
import auto.app.vo.TestReportVo;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import static auto.app.exetion.MainExetionMessage.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 杨森
 * @since 2022-07-24
 */
@Service
@Slf4j
public class TestCollectionServiceImpl extends ServiceImpl<TestCollectionDao, TestCollection> implements TestCollectionService {
    @Autowired
    private CaseService caseService;
    @Autowired
    private CollectionCaseService collectionCaseService;
    @Autowired
    private CaseDao caseDao;
    @Autowired
    private ParamsDao paramsDao;
    @Autowired
    private RestUtil restUtil;
    @Autowired
    private ResultService resultService;
    @Autowired
    private AutoExtractionService autoExtractionService;
    @Autowired
    private AutoGlobalService autoGlobalService;
    @Autowired
    private BeforeAssertionService beforeAssertionService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private DatabaseConnectService databaseConnectService;

    @Autowired
    private MysqlUtil mysqlUtil;

    @Autowired
    private AccountService  accountService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private AutoCollectionResultService autoCollectionResultService;

    @Autowired
    private AutoFileInfoService autoFileInfoService;

    @Autowired
    private OSSTemplate ossTemplate;

    @Value("${spring.file.path}")
    private String path;

    private static String redisCollect = "collection:%s";
    private static String redisSort = "sort:%s";
    private static String redisConfigCollection = "collectionConfig:%s";
    private static String redisConfig = "toConfigure:%s";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addTestCollection(AddTestCollectionFrom addTestCollectionFrom) throws MainExection {
        //获取测试用例id集合
        List<Integer> caseIdList = addTestCollectionFrom.getCaseIdList();
        ArrayList<CaseInterface> caseInterfaces = new ArrayList<>();
        //循环查询测试用例id是否存在
        caseIdList.stream().distinct().forEach(integer -> {
            CaseInterface byId = caseService.getById(integer);
            if (byId == null) {
                try {
                    throw new MainExection(CASEERROR.getCode(), CASEERROR.getMsg() + "测试用例id为" + integer);
                } catch (MainExection mainExection) {
                    mainExection.printStackTrace();
                }
            }
            caseInterfaces.add(byId);
        });
        //新增测试合集
        TestCollection testCollection = CommonUtil.copyOne(addTestCollectionFrom, TestCollection.class);
        testCollection.setCreateTime(LocalDateTime.now());
        testCollection.setCreateBy(UserGetAccount.getAccountId());
        testCollection.setCreateName(UserGetAccount.getAccountName());
        try {
            boolean save = this.save(testCollection);
        } catch (Exception e) {
            throw new MainExection(INSERTMYSQLCOLLECTION.getCode(), INSERTMYSQLCOLLECTION.getMsg());
        }
        //新增测试合集和测试用例关联关系
        List<CollectionCase> collectionCases = CommonUtil.copyList(caseInterfaces, CollectionCase.class);
        int i = 1;
        for (CollectionCase collectionCase : collectionCases) {
            collectionCase.setCollectionId(testCollection.getId());
            collectionCase.setCreateTime(LocalDateTime.now());
            collectionCase.setSort(i);
            i++;
        }
        try {
            boolean b = collectionCaseService.saveBatch(collectionCases);
        } catch (Exception e) {
            throw new MainExection(INSERTMYSQLCOLLECTIONCASE.getCode(), INSERTMYSQLCOLLECTIONCASE.getMsg());
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CasePageInfo CaselistCollection(CollectionCasePageFrom collectionCasePageFrom) throws MainExection {
        //获取测试合集id
        Integer collectionId = collectionCasePageFrom.getCollectionId();
        //查询测试合集存在不
        TestCollection testCollection = baseMapper.selectById(collectionId);
        if (testCollection == null) {
            throw new MainExection(SELECTCOLLECTERROR.getCode(), SELECTCOLLECTERROR.getMsg());
        }
        //查询关联的测试用例
        QueryWrapper<CollectionCase> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("collection_id", collectionId);
        List<CollectionCase> list = collectionCaseService.list(queryWrapper);
        if (list == null || list.size() == 0) {
            throw new MainExection(SELECTMYSQLCOLLECTIONCASE.getCode(), SELECTMYSQLCOLLECTIONCASE.getMsg());
        }
        //提取出测试用例的id和sort
        HashMap<Integer, Integer> hashMap = new HashMap<>();
        list.stream().forEach(collectionCase -> hashMap.put(collectionCase.getCaseId(), collectionCase.getSort()));
        //获取测试用例的id 查询处理
        List<Integer> collect = list.stream().map(CollectionCase::getCaseId).collect(Collectors.toList());
        //将测试用例id集合赋值到CollectionCasePageFrom类
        collectionCasePageFrom.setCaseList(collect);
        //当传入的接口名称不为空时进行判断且附值
        if (ObjectUtils.isNotEmpty(collectionCasePageFrom.getInterfaceName())) {
            collectionCasePageFrom.setInterfaceName("%" + collectionCasePageFrom.getInterfaceName() + "%");
        }
        Page<CaseDaoDto> page = new Page<>(collectionCasePageFrom.getCurrent(), collectionCasePageFrom.getSize());
        //查询出对应的测试用例
        Page<CaseDaoDto> caseDaoDtoPage = caseDao.listALlCollection(page, collectionCasePageFrom);
        List<CaseDaoDto> caseDaoDtos = caseDaoDtoPage.getRecords();
        //测试用例进行排序 从hashmap中取值
        caseDaoDtos.stream().forEach(caseDaoDto -> {
            Integer value = hashMap.get(caseDaoDto.getCaseId());
            if (value != null) {
                caseDaoDto.setSort(value);
            }
        });
        //set一个集合返回类并且赋值进去
        CasePageInfo casePageInfo = new CasePageInfo();
        casePageInfo.setTotal(caseDaoDtoPage.getTotal());
        casePageInfo.setCurrent(caseDaoDtoPage.getCurrent());
        casePageInfo.setSize(caseDaoDtoPage.getSize());
        casePageInfo.setRecords(caseDaoDtoPage.getRecords());
        casePageInfo.setTestCollection(testCollection);
        return casePageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean caseListSort(CollectionCaseSortFrom collectionCaseSortFrom) throws MainExection {
        //查询测试合集id是否存在
        Integer collectionId = collectionCaseSortFrom.getCollectionId();
        TestCollection testCollection = baseMapper.selectById(collectionId);
        if (testCollection == null) {
            throw new MainExection(SELECTCOLLECTERROR.getCode(), SELECTCOLLECTERROR.getMsg());
        }
        //查询关联的测试用例
        QueryWrapper<CollectionCase> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("collection_id", collectionId);
        List<CollectionCase> list = collectionCaseService.list(queryWrapper);
        //判断是否全部都排序了 若没有并指出哪个没排序
        if (list.size() != collectionCaseSortFrom.getCaseSortFromList().size()) {
            throw new MainExection(SORTNOTALLEROOR.getCode(), SORTNOTALLEROOR.getMsg());
        }
        //获取测试合集id关联的测试用例id集合
        List<Integer> mysqlCollect = list.stream().map(CollectionCase::getCaseId).collect(Collectors.toList());
        //对测试用例进行排序
        List<Integer> collect1 = collectionCaseSortFrom.getCaseSortFromList().stream().map(CaseSortFrom::getCaseId).collect(Collectors.toList());
        //先将集合中id和排序 存在hashmap中
        HashMap<Integer, Integer> hashMap = new HashMap<>();
        //hashMapOne用于判断sort排序是否重复
        HashMap<Integer, Integer> hashMapOne = new HashMap<>();
        collectionCaseSortFrom.getCaseSortFromList().stream().forEach(new Consumer<CaseSortFrom>() {
            @Override
            public void accept(CaseSortFrom caseSortFrom) {
                hashMap.put(caseSortFrom.getCaseId(), caseSortFrom.getSort());
                hashMapOne.put(caseSortFrom.getSort(), caseSortFrom.getCaseId());
            }
        });
        //判断hashMap 和hashMapOne的长度可以知道sort是否重复
        if (hashMap.size() != hashMapOne.size()) {
            throw new MainExection(SORTDISTANTERROR.getCode(), SORTDISTANTERROR.getMsg());
        }
        //判断collect1中的测试用例id是否存在关联关系中
        collect1.stream().forEach(integer -> {
            if (!mysqlCollect.contains(integer)) {
                try {
                    throw new MainExection(SELECTMYSQLCOLLECTIONCASE.getCode(), SELECTMYSQLCOLLECTIONCASE.getMsg() + "id为" + integer);
                } catch (MainExection mainExection) {
                    mainExection.printStackTrace();
                }
            }
        });
        //对查询的用例进行排序赋值
        list.stream().forEach(collectionCase -> {
            Integer integer = hashMap.get(collectionCase.getCaseId());
            if (integer != null) {
                collectionCase.setSort(integer);
            }
        });
        try {
            boolean b = collectionCaseService.updateBatchById(list);
            return b;
        } catch (Exception e) {
            throw new MainExection(INSERTSORTERROT.getCode(), INSERTSORTERROT.getMsg());
        }
    }

    @Override
    public CollectionPageInfo list(CollectionPage collectionPage) {
        LambdaQueryWrapper<TestCollection> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(TestCollection::getCreateTime);
        CollectionPage collectionPage1 = baseMapper.selectPage(collectionPage, lambdaQueryWrapper);
        return CommonUtil.copyOne(collectionPage1, CollectionPageInfo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteCase(CollectionCaseDeleteFrom collectionCaseDeleteFrom) throws MainExection {
        //查询测试合集是否存在
        Integer collectionId = collectionCaseDeleteFrom.getCollectionId();
        TestCollection testCollection = baseMapper.selectById(collectionId);
        if (testCollection == null) {
            throw new MainExection(SELECTCOLLECTERROR.getCode(), SELECTCOLLECTERROR.getMsg());
        }
        //查询关联的测试用例
        QueryWrapper<CollectionCase> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("collection_id", collectionId);
        List<CollectionCase> list = collectionCaseService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            throw new MainExection(SELECTMYSQLCOLLECTIONCASE.getCode(), SELECTMYSQLCOLLECTIONCASE.getMsg());
        }
        //取出关联的测试用例id
        List<Integer> collect = list.stream().map(CollectionCase::getCaseId).collect(Collectors.toList());
        //判断传id集合是否存在关联关系中
        List<Integer> caseIdList = collectionCaseDeleteFrom.getCaseIdList();
        if (caseIdList == null || caseIdList.size() == 0) {
            throw new MainExection(DELETECASETELECTIONERROR.getCode(), DELETECASETELECTIONERROR.getMsg());
        }
        collectionCaseDeleteFrom.getCaseIdList().stream().forEach(integer -> {
            if (!collect.contains(integer)) {
                try {
                    throw new MainExection(SELECTMYSQLCOLLECTIONCASE.getCode(), SELECTMYSQLCOLLECTIONCASE.getMsg() + "caseid:" + integer);
                } catch (MainExection mainExection) {
                    mainExection.printStackTrace();
                }
            }
        });

        //构造查询条件 查询出需要删除的关联表对象
        QueryWrapper<CollectionCase> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("collection_id", collectionId).in("case_id", collectionCaseDeleteFrom.getCaseIdList());
        //查询出删除集合的关联表的对象
        List<CollectionCase> list1 = collectionCaseService.list(queryWrapper1);
        //如果集合不为空
        if (!CollectionUtils.isEmpty(list1)) {
            //取出要删除的关联表的id
            List<Integer> collect1 = list1.stream().map(CollectionCase::getId).collect(Collectors.toList());
            try {
                boolean b = collectionCaseService.removeByIds(collect1);
                return b;
            } catch (Exception e) {
                throw new MainExection(DELETECOLLECTCASEMYSQLERROR.getCode(), DELETECOLLECTCASEMYSQLERROR.getMsg());
            }
        }
        //删除结果集中的合集结果 避免导出时导出之前的测试报告
        LambdaQueryWrapper<Result> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Result::getCollectionId,collectionId).in(Result::getCaseId,collectionCaseDeleteFrom.getCaseIdList());
        boolean remove = resultService.remove(lambdaQueryWrapper);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addTestCase(AddTestCollectionCaseFrom addTestCollectionCaseFrom) throws MainExection {
        //查询测试合集是否存在
        TestCollection testCollection = baseMapper.selectById(addTestCollectionCaseFrom.getId());
        if (testCollection == null) {
            throw new MainExection(SELECTCOLLECTERROR.getCode(), SELECTCOLLECTERROR.getMsg());
        }
        //判断测试用例是否存在
        List<CaseInterface> list = caseService.list();
        List<Integer> collect = list.stream().map(CaseInterface::getCaseId).collect(Collectors.toList());
        //判断测试用例是否已经在合集下新增
        QueryWrapper<CollectionCase> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("collection_id", addTestCollectionCaseFrom.getId());
        List<CollectionCase> list1 = collectionCaseService.list(queryWrapper);
        List<Integer> integerList = list1.stream().map(CollectionCase::getCaseId).collect(Collectors.toList());
        //新增关联关系到关联表
        ArrayList<CollectionCase> arrayList = new ArrayList<>();
        //判断传入的测试用例是否存在
        for (Integer integer : addTestCollectionCaseFrom.getCaseIdList()) {
            //判断测试用例是否存在
            if (!collect.contains(integer)) {
                throw new MainExection(CASEERROR.getCode(), CASEERROR.getMsg() + "caseId:" + integer);
            }
            //判断测试用例是否已经在合集下存在
            if (integerList.contains(integer)) {
                throw new MainExection(COLLECTIONCASEISSAVE.getCode(), COLLECTIONCASEISSAVE.getMsg() + "caseId:" + integer);
            }
            //新增关联关系到关联表
            arrayList.add(CollectionCase.builder().createTime(LocalDateTime.now()).collectionId(addTestCollectionCaseFrom.getId()).caseId(integer).build());
        }
        //默认排序
        Optional<Integer> max = list1.stream().map(CollectionCase::getSort).max((o1, o2) -> o1 - o2);
        Integer integer = max.get() + 1;
        for (CollectionCase collectionCase : arrayList) {
            collectionCase.setSort(integer);
            integer += 1;
        }
        //新增关联关系到关联表 入库
        try {
            boolean b = collectionCaseService.saveBatch(arrayList);
            return b;
        } catch (Exception e) {
            throw new MainExection(INSERTMYSQLCOLLECTIONCASE.getCode(), INSERTMYSQLCOLLECTIONCASE.getMsg());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean execute(Integer id,Boolean bool,Integer acconutId,String accountName) throws Exception {
        //查询测试合集是否存在
        TestCollection testCollection = baseMapper.selectById(id);
        if (ObjectUtil.isNull(testCollection)) {
            throw new MainExection(SELECTCOLLECTERROR.getCode(), SELECTCOLLECTERROR.getMsg());
        }
        //查询出关联的测试用例
        QueryWrapper<CollectionCase> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("collection_id", id);
        List<CollectionCase> list1 = collectionCaseService.list(queryWrapper);
        //判断关联的测试用例下 是否全部排序
        //将排序的值存入hashmap中方便使用
        HashMap<Integer, Integer> hashMap = new HashMap<>();
        for (CollectionCase collectionCase : list1) {
            if (collectionCase.getSort() == null) {
                throw new MainExection(NOSORTERROT.getCode(), NOSORTERROT.getMsg());
            }
            hashMap.put(collectionCase.getCaseId(), collectionCase.getSort());
        }
        //查询出测试集合需要的数据
        List<CaseDaoDto> caseDaoDtos = caseDao.listExecute(list1.stream().map(CollectionCase::getCaseId).collect(Collectors.toList()));
        //将排序的值筛入List<CaseDaoDto>中 通过hashmap
        caseDaoDtos.stream().forEach(caseDaoDto -> caseDaoDto.setSort(hashMap.get(caseDaoDto.getCaseId())));
        //按照sort字段升序排序
        List<CaseDaoDto> collect = caseDaoDtos.stream().sorted(Comparator.comparing(CaseDaoDto::getSort)).collect(Collectors.toList());
        //循环执行用例
        //循环执行的时候 需要按顺序执行 提取关联数据
        Integer i = 1;
        for (CaseDaoDto caseDaoDto : collect) {
            callCase(caseDaoDto.getCaseId(), id, i);
            i++;
        }
        //创建测试合集执行表
        AutoCollectionResult autoCollectionResult=null;
        if (bool){
            autoCollectionResult = AutoCollectionResult.builder()
                    .id(IdUtil.simpleUUID())
                    .collectionId(id)
                    .excuteTime(LocalDateTime.now())
                    .excuteType("定时任务")
                    .createTime(LocalDateTime.now()).build();
            autoCollectionResultService.save(autoCollectionResult);
        }else{
            autoCollectionResult = AutoCollectionResult.builder()
                    .id(IdUtil.simpleUUID())
                    .collectionId(id)
                    .excuteTime(LocalDateTime.now())
                    .excuteType("后台执行")
                    .createTime(LocalDateTime.now())
                    .excuteId(acconutId)
                    .excuteName(accountName)
                    .build();
            autoCollectionResultService.save(autoCollectionResult);
        }
        //获取测试用例执行结果
        List<TestReportVo> testReportVos = resultService.export(id);
        PdfReport report=new PdfReport();
        ByteArrayOutputStream byteArrayOutputStream=null;
        if (!bool){
            byteArrayOutputStream = report.pdfReportExcult(testReportVos,accountName);
        }else {
            byteArrayOutputStream = report.pdfReportExcult(testReportVos,null);
        }
        String name="测试报告" + IdUtil.simpleUUID() + ".pdf";
        AutoFileInfo autoFileInfo=null;
        //上传测试报告到文件服务器 保存
        if (bool){
            //这里将测试报告存在了本地 不可取 需要修改
            if (ObjectUtil.isNotNull(testCollection.getCreateBy())){
                Account byId = accountService.getById(testCollection.getCreateBy());
                emailService.sendAttachmentsMailArray(byId.getEmail(),"测试报告"+LocalDateTime.now(),name,byteArrayOutputStream);
            }
            //上传文件服务
            autoFileInfo = ossTemplate.uploadFile(name, new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
            autoFileInfo.setDataId(autoCollectionResult.getId());
            autoFileInfo.setFileType("PDF");
        }else{
            //后台执行 需要生成文件 且上传文件服务器
            autoFileInfo = ossTemplate.uploadFile(name, new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
            autoFileInfo.setDataId(autoCollectionResult.getId());
            autoFileInfo.setFileType("PDF");
        }
        autoFileInfoService.save(autoFileInfo);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteList(TestCollectionDeleteFrom testCollectionDeleteFrom) throws MainExection {
        //根据测试合集id查询测试合集数据
        List<Integer> ids = testCollectionDeleteFrom.getIds();
        LambdaQueryWrapper<TestCollection> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(TestCollection::getId, ids);
        List<TestCollection> testCollections = baseMapper.selectList(lambdaQueryWrapper);
        if (ObjectUtils.isEmpty(testCollections)) {
            throw new MainExection(TESTCOLLECTIONSELECTERROR.getCode(), TESTCOLLECTIONSELECTERROR.getMsg());
        } else {
            int delete = baseMapper.delete(lambdaQueryWrapper);
        }
        //根据测试合集id 查询关联表数据
        LambdaQueryWrapper<CollectionCase> caseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        caseLambdaQueryWrapper.in(CollectionCase::getCollectionId, ids);
        List<CollectionCase> collectionCases = collectionCaseService.list(caseLambdaQueryWrapper);
        if (ObjectUtils.isEmpty(collectionCases)) {
            throw new MainExection(DELETECOLLECTCASEMYSQLERROR.getCode(), DELETECOLLECTCASEMYSQLERROR.getMsg());
        } else {
            boolean remove = collectionCaseService.remove(caseLambdaQueryWrapper);
        }
        return true;
    }

    //关联提取 配置
    //单个用例执行方法
    private String callCase(Integer caseId, Integer collectionId, Integer sort) throws MainExection {
        //获取关联提取的参数 我想使用redis 将全局使用的 以及提取关联的东西先放到redis中 方便获取
        //根据case_id 判断用例是否存在
        CaseInterface aCaseInterface = caseDao.selectById(caseId);
        if (null == aCaseInterface) throw new MainExection(CASEERROR.getCode(), CASEERROR.getMsg());
        //用例存在 查询相关信息
        CaseDaoDto dtoByCaseId = caseDao.findDtoByCaseId(caseId);
        //校验数据
        if(ObjectUtil.isNull(dtoByCaseId.getParameterType()) || ObjectUtil.isNull(dtoByCaseId.getRequsetMethod())
                || ObjectUtil.isNull(dtoByCaseId.getRequestPath()) || ObjectUtil.isNull(dtoByCaseId.getIp())){
            throw new MainExection(CASEINTERFACEERROR.getCode(), CASEINTERFACEERROR.getMsg());
        }
        //数据校验通过 对ip和端口 路径进行组装存在ip中
        if (ObjectUtil.isNotNull(dtoByCaseId.getPort())) {
            dtoByCaseId.setIp(dtoByCaseId.getIp() + ":" + dtoByCaseId.getPort() + dtoByCaseId.getRequestPath());
        } else {
            dtoByCaseId.setIp(dtoByCaseId.getIp() + dtoByCaseId.getRequestPath());
        }
        //地址组装通过获取请求参数 请求体
        List<Params> paramsList = paramsDao.selectList(new QueryWrapper<Params>().eq("case_id", dtoByCaseId.getCaseId()));
        List<Params> paramHeader=new ArrayList<>();
        List<Params> paramsBody=new ArrayList<>();
        List<Params> urlParams =new ArrayList<>();
        for (Params params : paramsList) {
            if (ObjectUtil.isNull(params.getType())){
                log.info("测试用例ID为"+caseId+"的参数params:"+params.getId()+"无类型");
            }
            if (params.getType().equals("H")){
                paramHeader.add(params);
            }
            if (params.getType().equals("B")){
                paramsBody.add(params);
            }
            //如果是url传参 需要提取出来
            if (dtoByCaseId.getUrlParameterTransfer() == 1){
                if (params.getType().equals("C")){
                    urlParams.add(params);
                }
            }
        }
        //获取请求方式
        HttpMethod method = CommonUtil.getMethod(dtoByCaseId.getRequsetMethod());
        //判断请求头 和请求头是否为空 非空的存入map集合
        MultiValueMap<String, String> hashMapHeader = new LinkedMultiValueMap<>();
        HashMap<String, Object> hashMapBody = new HashMap<>();
//        HashMap<String, String> hashMapHeader=new HashMap<>();
        //进行全局参数设置 查询出全部启用的参数
        List<AutoGlobal> autoGlobals = autoGlobalService.autoGlobalListCase();
        for (AutoGlobal autoGlobal : autoGlobals) {
            //如果是H就加入请求头
            if (autoGlobal.getParameType().equals("H")) {
                hashMapHeader.add(autoGlobal.getParameName(), autoGlobal.getDefaultValue());
            } else if (autoGlobal.getParameType().equals("B")) {
                //如果是请求体就加入请求体
                hashMapBody.put(autoGlobal.getParameName(), autoGlobal.getDefaultValue());
            }
        }
        ObjectUtil.isNull(paramHeader);
        //若全局参数和单个测试用例中的参数重合 优先使用全局参数
        if (paramHeader.size() > 0) {
            paramHeader.forEach(params -> {
                //判断是否存在相同的参数名的全局参数
                List<String> strings = hashMapHeader.get(params.getParamName());
                //如果存在则数组的长度大于0
                if (CollectionUtils.isEmpty(strings)) {
                    hashMapHeader.add(params.getParamName(), params.getParamValue());
                }
            });
        }
        //根据请求参数是否为数组 走不同的逻辑 赋值进入请求体中
        if (paramsBody.size() > 0) {
            for (Params params : paramsBody) {
                //判断是否存在相同的参数名的全局参数
                Object o = hashMapBody.get(params.getParamName());
                if (ObjectUtils.isEmpty(o)) {
                    if (params.getParamType() == 0) {
                        hashMapBody.put(params.getParamName(), params.getParamValue());
                    } else {
                        hashMapBody.put(params.getParamName(), JSONUtil.parseArray(params.getParamValue()));
                    }
                }
            }
        }
        //redis查询关联上一个的提取
        Object o = redisTemplate.opsForHash().get(String.format(redisCollect, collectionId), String.format(redisSort, sort - 1));
        if (!ObjectUtils.isEmpty(o)) {
            List<AutoExtractionRedis> autoExtractionRedis = CommonUtil.castList(o, AutoExtractionRedis.class);
            for (AutoExtractionRedis autoExtractionRedi : autoExtractionRedis) {
                hashMapBody.put(autoExtractionRedi.getParameter(), autoExtractionRedi.getValue());
            }
        }
        //从redis取出全局参数 存入hamp中
        Map<String, List<AutoExtractionRedis>> entries = redisTemplate.opsForHash().entries(String.format(redisConfigCollection, collectionId));
        if (!ObjectUtils.isEmpty(entries)) {
            Iterator<Map.Entry<String, List<AutoExtractionRedis>>> iterator = entries.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, List<AutoExtractionRedis>> entry = iterator.next();
                String key = entry.getKey();
                List<AutoExtractionRedis> value = entry.getValue();
                for (AutoExtractionRedis autoExtractionRedis : value) {
                    hashMapBody.put(autoExtractionRedis.getParameter(), autoExtractionRedis.getValue());
                }
            }
        }
        //存入集合后进行参数类型判断
        HashMap<String, String> type = CommonUtil.getType(dtoByCaseId.getParameterType());
        //将请求头设置的信息 加入请求头中
        for (String key : type.keySet()) {
            hashMapHeader.add(key, type.get(key));
        }
        //进行接口调用
        try {
            //执行成功无异常录入执行结果
            ResponseEntity<String> execute = null;
            //判断是否url传参
            if (dtoByCaseId.getUrlParameterTransfer() == 1) {
                if (CollectionUtils.isEmpty(urlParams)) {
                    throw new MainExection(URLPARAMSISNULL.getCode(), URLPARAMSISNULL.getMsg());
                }
                StringBuffer urlIp = new StringBuffer(dtoByCaseId.getIp());
                for (int i = 0; i < urlParams.size(); i++) {
                    urlIp.append("/").append(urlParams.get(i).getParamValue());
                }
                String urlString = urlIp.toString();
                execute = restUtil.execute(hashMapBody, urlString, method, hashMapHeader);
            } else {
                //执行成功无异常录入执行结果
                execute = restUtil.execute(hashMapBody, dtoByCaseId.getIp(), method, hashMapHeader);
            }
            //断言
            List<BeforeAssertionChickInfo> beforeAssertionChickInfos = beforeAssertionService.beforeAssertionChick(BeforeAssertionChickFrom.builder().caseId(caseId).jsonString(execute.getBody()).build());
            //无断言
            if (beforeAssertionChickInfos == null) {
                Result result = Result.builder().caseId(caseId).createDate(LocalDateTime.now()).status("S").result(execute.getBody()).collectionId(collectionId).message("执行成功").build();
                resultService.addTestCollection(result);
            } else {
                AtomicReference<String> message = new AtomicReference<>("");
                beforeAssertionChickInfos.forEach(beforeAssertionChickInfo -> {
                    if (beforeAssertionChickInfo.getResult()) {
                        log.info(beforeAssertionChickInfo.getResult() + beforeAssertionChickInfo.getMsg());
                    } else {
                        log.info(beforeAssertionChickInfo.getResult() + beforeAssertionChickInfo.getMsg());
                        message.set(message + beforeAssertionChickInfo.getMsg());
                    }
                });
                String s = message.toString();
                if (ObjectUtils.isNotEmpty(s)) {
                    Result result = Result.builder().caseId(caseId).createDate(LocalDateTime.now()).status("F").result(execute.getBody()).collectionId(collectionId).message(s).build();
                    resultService.addTestCollection(result);
                } else {
                    Result result = Result.builder().caseId(caseId).createDate(LocalDateTime.now()).status("S").result(execute.getBody()).collectionId(collectionId).message("执行成功").build();
                    resultService.addTestCollection(result);
                }
            }
            try {
                //后置操作执行MYSQL
                List<DatabaseConnect> databaseConnects = databaseConnectService.listDatabaseConnectState(caseId);
                if (ObjectUtil.isNotNull(databaseConnects) && databaseConnects.size()>0){
                    for (DatabaseConnect databaseConnect : databaseConnects) {
                        MysqlReturn mysqlReturn = mysqlUtil.excult(databaseConnect.getDatabaseId());
                    }
                }
            }catch (Exception e){
                log.info("后置操作mysql执行报错,请检查sql");
                log.info(e.getMessage());
            }
//            关联提取 准备使用redis
            QueryWrapper<AutoExtraction> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("case_id", caseId);
            List<AutoExtraction> list = autoExtractionService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(list)) {
                List<AutoExtractionRedis> autoExtractionRedis = new ArrayList<>();
                List<AutoExtractionRedis> autoExtractionConfig = new ArrayList<>();
                ResponseEntity<String> finalExecute = execute;
                list.forEach(autoExtraction -> {
                    String josnValue = CommonUtil.findJosnValue(autoExtraction.getParameter(), finalExecute.getBody());
                    if (josnValue != null) {
                        autoExtraction.setValue(josnValue);
                        autoExtractionService.updateById(autoExtraction);
                        AutoExtractionRedis autoExtractionRedis1 = CommonUtil.copyOne(autoExtraction, AutoExtractionRedis.class);
                        if (autoExtractionRedis1.getToConfigure().equals("B")) {
                            autoExtractionRedis.add(autoExtractionRedis1);
                        } else {
                            autoExtractionConfig.add(autoExtractionRedis1);
                        }
                    } else {
                        log.info("测试合集:" + collectionId + "测试用例id：" + caseId + "的关联提取值:" + autoExtraction.getParameter() + "不存在");
                    }
                });
                //存入单下个使用的关联参数
                redisTemplate.opsForHash().put(String.format(redisCollect, collectionId), String.format(redisSort, sort), autoExtractionRedis);
                //存在全局参数
                redisTemplate.opsForHash().put(String.format(redisConfigCollection, collectionId), String.format(redisConfig, sort), autoExtractionConfig);
            } else {
                log.info("测试用例id：" + caseId + "的测试用例无关联提取");
            }
            String s = JSONUtil.toJsonStr(execute.getBody());
            return "执行成功";
        } catch (Exception e) {
            //调用接口报错
            log.info(e.getMessage());
            Result result = Result.builder().caseId(caseId).createDate(LocalDateTime.now()).status("F").result("执行失败").collectionId(collectionId).message(e.getMessage()).build();
            resultService.addTestCollection(result);
            return "执行失败";
        }
    }

}
